package com.polaris.live.viewmodel.party

import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.blankj.utilcode.util.StringUtils
import com.polaris.live.common.cacha.UserManager
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.manager.withRetryNow
import com.polaris.live.common.network.AppException
import com.polaris.live.common.network.HTTP_ERROR_CODE
import com.polaris.live.common.network.launchLoading
import com.polaris.live.common.network.request
import com.polaris.live.common.network.requestLoading
import com.polaris.live.common.network.state.ResultState
import com.polaris.live.common.network.state.paresException
import com.polaris.live.common.network.state.paresResult
import com.polaris.live.common.util.ToastGravity
import com.polaris.live.constant.UserConst
import com.polaris.live.im.sfs.COMMAND_LIVE_QUIT
import com.polaris.live.im.sfs.COMMAND_LIVE_RECOVER
import com.polaris.live.im.sfs.COMMAND_LIVE_STOP
import com.polaris.live.im.sfs.PARTY_LIVEKICKUSER
import com.polaris.live.im.sfs.PARTY_LIVESITEDOWN
import com.polaris.live.im.sfs.PARTY_LIVESITEKICK
import com.polaris.live.im.sfs.PARTY_LIVESITELOCK
import com.polaris.live.im.sfs.PARTY_LIVESITEMICBAN
import com.polaris.live.im.sfs.PARTY_LIVESITEUP
import com.polaris.live.im.sfs.PARTY_LIVESITEVIDEOBAN
import com.polaris.live.im.sfs.PARTY_LIVESITEVIDEOSWITCH
import com.polaris.live.im.sfs.bean.live.LiveKickUserMessage
import com.polaris.live.im.sfs.bean.live.LiveMsgIdMessage
import com.polaris.live.im.sfs.bean.live.LiveQuitMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteDownMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteKickMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteLockMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteMicMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteUpMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteVideoBanMessage
import com.polaris.live.im.sfs.bean.live.LiveSiteVideoSwitchMessage
import com.polaris.live.im.sfs.bean.live.LiveStopMessage
import com.polaris.live.im.sfs.bean.live.NullReceiptMessage
import com.polaris.live.im.sfs.bean.live.SendLiveNoticeMessage
import com.polaris.live.im.sfs.core.SmartFoxQueueManager
import com.polaris.live.im.sfs.core.bean.resolveResponse
import com.polaris.live.manager.DownFileManager
import com.polaris.live.net.liveService
import com.polaris.live.net.userService
import com.polaris.live.resp.back_resp.LivePasswordResp
import com.polaris.live.resp.back_resp.LiveStopReceiptResp
import com.polaris.live.resp.back_resp.LiveSubsidyIndicatorResp
import com.polaris.live.resp.back_resp.LiveWelcomeResp
import com.polaris.live.resp.back_resp.LiveWelcomeSpeechResp
import com.polaris.live.resp.event.MusicUpSeatEvent
import com.polaris.live.resp.go_resp.InviteSiteBean
import com.polaris.live.resp.go_resp.SettingModifyBean
import com.polaris.live.translation.R
import com.polaris.live.utils.file.FileUtils
import com.polaris.live.viewmodel.party.base.BasePartyFragmentModel
import kotlinx.coroutines.Job
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import org.greenrobot.eventbus.EventBus
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicBoolean

/**
 * PartyAnchorFragmentModel  主播Model
 *
 * @author Created by 天晴 on 2024/2/24 11:15
 * @since 1.0.0
 **/
open class PartyAnchorFragmentModel : BasePartyFragmentModel() {

    /**
     * 获取欢迎语
     */
    val welcomeSpeechData = MutableLiveData<ResultState<LiveWelcomeSpeechResp>>()
    fun welcomeSpeech() {
        request(
            { liveService.welcomeSpeech() },
            welcomeSpeechData
        )
    }

    /**
     * 更新欢迎语
     */
    val welcomeSpeechUpdateData = MutableLiveData<ResultState<LiveWelcomeSpeechResp>>()
    fun welcomeSpeechUpdate(content: String) {
        request(
            { liveService.welcomeSpeechUpdate(LiveWelcomeResp(content)) },
            welcomeSpeechUpdateData
        )
    }

    /**
     * 获取语聊房密码
     */
    val getPasswordData = MutableLiveData<ResultState<LivePasswordResp>>()
    fun getPassword() {
        request(
            { liveService.getPassword() },
            getPasswordData
        )
    }

    /**
     * 设置语聊房密码
     */
    val setPasswordData = MutableLiveData<ResultState<LivePasswordResp>>()
    fun setPassword(password: String) {
        requestLoading(
            { liveService.setPassword(LivePasswordResp(password)) },
            setPasswordData
        )
    }

    /**
     * 删除语聊房密码
     */
    val deletePasswordData = MutableLiveData<ResultState<Any>>()
    fun deletePassword() {
        requestLoading(
            { liveService.deletePassword() },
            deletePasswordData
        )
    }

    /**
     * 踢出房间
     */
    fun kickUser(userid: Long, anchorId: Long, roomId: String? = null) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVEKICKUSER,
                    LiveKickUserMessage(userid, anchorId, roomId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 踢下麦位
     */
    fun siteKick(userid: Long, anchorId: Long) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEKICK,
                    LiveSiteKickMessage(userid, anchorId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 开关禁麦
     */
    fun siteMic(userid: Long, mic: Boolean, anchorId: Long) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEMICBAN,
                    LiveSiteMicMessage(userid, mic, anchorId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 禁视频
     */
    fun siteVideo(userid: Long, ban: Boolean, anchorId: Long) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEVIDEOBAN,
                    LiveSiteVideoBanMessage(userid, ban, anchorId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 开关视频
     */
    fun videoSwitch(video: Boolean, anchorId: Long) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEVIDEOSWITCH,
                    LiveSiteVideoSwitchMessage(video, anchorId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 位置上下锁
     */
    val siteLockData = MutableLiveData<ResultState<LiveSiteLockMessage>>()
    fun siteLock(site: Int, lock: Boolean, anchorId: Long) {
        launchLoading {
            try {
                val resp = SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITELOCK,
                    LiveSiteLockMessage(site, lock, anchorId)
                )
                val data = resp.receipt.resolveResponse<LiveSiteLockMessage>()
                if (data != null) {
                    siteLockData.value = ResultState.onAppSuccess(data)
                } else {
                    siteLockData.value =
                        ResultState.onAppError(AppException(HTTP_ERROR_CODE, "Data is null"))
                }
            } catch (t: Throwable) {
                if (t is AppException) {
                    ToastGravity.showGravity(t.message)
                }
            }
        }
    }

    /**
     * 邀请上麦
     */
    fun partyInviteSite(userid: Long, site: Int?, liveId: Long) {
        requestLoading(
            { liveService.partyInviteSite(InviteSiteBean(site, userid, liveId)) },
            {
                ToastGravity.showGravity(R.string.invitation_successful)
            }, {
                ToastGravity.showGravity(it.errorMsg)
            }
        )
    }

    //关闭直播间
    val stopLiveLiveData = MutableLiveData<ResultState<LiveStopReceiptResp>>()
    fun stopLive(liveId: Long, needLoading: Boolean, roomId: String? = null) {
        viewModelScope.launch {
            try {
                if (needLoading) {
                    showLoading(StringUtils.getString(R.string.loading))
                }
                val resp = SmartFoxQueueManager.sendLiveMessage(
                    COMMAND_LIVE_STOP,
                    LiveStopMessage(liveId, roomId = roomId)
                )
                val data = resp.receipt.resolveResponse<LiveStopReceiptResp>()
                if (data != null) {
                    stopLiveLiveData.paresResult(data)
                } else {
                    stopLiveLiveData.paresException(NullPointerException("data is null"))
                }
            } catch (t: Throwable) {
                stopLiveLiveData.paresException(t)
            } finally {
                dismissDialog()
            }
        }
    }

    //主播通知消息pag下载
    private var mIsDownloading = AtomicBoolean(false)   //是否正在下载中
    private val mLoadQueue = ConcurrentLinkedQueue<SendLiveNoticeMessage>() //下载队列
    private var mPagJob: Job? = null
    val mDownLoadLiveData = MutableLiveData<SendLiveNoticeMessage>()

    fun downLoadPag(sendLiveNoticeMessage: SendLiveNoticeMessage) {
        if (mIsDownloading.get()) {
            mLoadQueue.add(sendLiveNoticeMessage)
            return
        }
        mIsDownloading.set(true)
        mPagJob = viewModelScope.launch(CoroutineScopeManager.ioDispatcher) {
            try {
                val loadFileCallback =
                    DownFileManager.loadFileCallback(
                        FileUtils.getPagFile(),
                        sendLiveNoticeMessage.titleImage
                    )
                withContext(CoroutineScopeManager.mainDispatcher) {
                    mIsDownloading.set(false)
                    loadFileCallback?.second?.let {
                        mDownLoadLiveData.value = sendLiveNoticeMessage
                    }
                    mLoadQueue.poll()?.let { downLoadPag(it) }
                }
            } finally {
                if (coroutineContext[Job] == mPagJob) {
                    mPagJob = null
                }
            }
        }
    }

    //恢复直播间，只有主播调用
    val recoverFailureLiveData = MutableLiveData<Throwable>()
    fun recoverLive(roomId: String? = null) {
        viewModelScope.launch {
            try {
                //这里立即重试一次
                withRetryNow {
                    SmartFoxQueueManager.sendLiveMessage(COMMAND_LIVE_RECOVER, LiveMsgIdMessage(roomId))
                }
            } catch (t: Throwable) {
                //恢复直播间失败，退出
                recoverFailureLiveData.value = t
            }
        }
    }

    //直播补贴指标
    val mSubsidyLiveData = MutableLiveData<ResultState<LiveSubsidyIndicatorResp>>()
    fun getSubsidy() {
        request({ liveService.subsidies() }, mSubsidyLiveData)
    }

    //主播退出直播间
    val exitLiveLiveData = MutableLiveData<Boolean>()
    fun exitLive(anchorId: Long, roomId: String? = null) {
        viewModelScope.launch {
            val deferred = async {
                withContext(NonCancellable + CoroutineScopeManager.ioDispatcher) {
                    try {
                        SmartFoxQueueManager.sendLiveMessage(
                            COMMAND_LIVE_QUIT,
                            LiveQuitMessage(anchorId, roomId)
                        )
                    } catch (_: Throwable) {
                    }
                }
            }

            withTimeoutOrNull(500) {
                deferred.await()
            }

            exitLiveLiveData.postValue(true)
        }
    }

    val liveSiteUpData = MutableLiveData<ResultState<NullReceiptMessage>>()

    //上麦
    fun liveSiteUp(anchorId: Long, invite: Boolean = false, site: Int? = null, upSiteType: Int? = null) {
        launchLoading {
            try {
                val resp = SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEUP,
                    LiveSiteUpMessage(site, invite, anchorId, upSiteType)
                )
                val data = resp.receipt.resolveResponse<NullReceiptMessage>()
                if (data != null) {
                    EventBus.getDefault().post(MusicUpSeatEvent(true))
                    liveSiteUpData.value = ResultState.onAppSuccess(data)
                } else {
                    liveSiteUpData.value =
                        ResultState.onAppError(AppException(HTTP_ERROR_CODE, "Data is null"))
                }
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    //观众下麦
    fun liveSiteDown(anchorId: Long) {
        launchLoading {
            try {
                SmartFoxQueueManager.sendLiveMessage(
                    PARTY_LIVESITEDOWN,
                    LiveSiteDownMessage(anchorId)
                )
            } catch (t: Throwable) {
                ToastGravity.showGravity(t.message)
            }
        }
    }

    /**
     * 修改用户设置
     */
    fun settingModify(@UserConst.SettingType type: Int, state: Int) {
        requestLoading({ userService.settingModify(SettingModifyBean(type, state)) }, {
            when (type) {
                UserConst.UserSetting.MINIMIZE -> {
                    UserManager.getUser().setting?.minimizeExitRoom = state
                }
            }
        }, {
            ToastGravity.showGravity(it.errorMsg)
        })
    }
}